#include "SceneManager.h"

SceneManager::SceneManager(void)
{
	Init();
	m_touch = new Touch();
	m_collidMgr = new CollisionManager();
	m_selectedObject = NULL;
}

SceneManager::~SceneManager(void)
{
}

EObjectType SceneManager::GetTypeObject(char *typeStr)
{
	if (strcmp(typeStr, OBJ_TYPE_RECT) == 0)
	{
		return RECTANGLE;
	} else if (strcmp(typeStr, OBJ_TYPE_CIRCLE) == 0)
	{
		return CIRCLE;
	} else if (strcmp(typeStr, OBJ_TYPE_PLANE) == 0)
	{
		return PLANE;
	}

	return NONE;
}

void SceneManager::Init()
{
	printf("SceneManager: Init! \n");
	
	FILE* pFile ; //= fopen(k_FILE_OBJECT, "r");
	fopen_s(&pFile, k_FILE_OBJECT, "r");
	if (pFile != NULL)
	{
		int numObject = 0;
		float posX, posY;
		int velo = 0;

		char type[k_TYPE_MAX_LENG + 1];

		fscanf(pFile, FORM_OBJ_NUMBER, &numObject);
		//printf("num obj: %d \n", numObject);
		for (int i = 0; i < numObject; i++)
		{
			fscanf(pFile, FORM_OBJ_TYPE, type);
			//printf(" == obj: %s \n", type);

			int objectType = GetTypeObject(type);
			
			switch (objectType)
			{
			case RECTANGLE:
				int width, height;
				posX = posY = 0;
				width = height = 1;
				
				fscanf(pFile, FORM_POS_RECT, &posX, &posY, &width, &height);
				printf("RECT:: %d, %d, %d, %d \n", posX, posY, width, height);
				fscanf(pFile, FORM_OBJ_VELO, &velo);
				//printf("velo :: %d\n", velo);
				Rectangles* _rect;
				_rect = new Rectangles(posX, posY, width, height);
				_rect->SetVelocityDefault((float)velo);

				this->AddObject(_rect);

				break;

			case CIRCLE:
				int radius;
				posX = posY = 0;
				radius = 0;
				fscanf(pFile, FORM_POS_CIRCLE, &posX, &posY, &radius);
				printf("CIRCLE:: %d, %d, %d \n", posX, posY, radius);
				fscanf(pFile, FORM_OBJ_VELO, &velo);
				//printf("velo :: %d\n", velo);
				Circle* _cirlce;
				_cirlce = new Circle(posX, posY, radius);
				_cirlce->SetVelocityDefault((float)velo);

				this->AddObject(_cirlce);

				break;

			case PLANE:
				int posX2, posY2;
				posX = posY = 0;
				posX2 = posY2 = 0;
				
				fscanf(pFile, FORM_POS_RECT, &posX, &posY, &posX2, &posY2);
				printf("PLANE:: %d, %d, %d, %d \n", posX, posY, posX2, posY2);
				fscanf(pFile, FORM_OBJ_VELO, &velo);
				//printf("velo :: %d\n", velo);
				Plane* _plane;
				_plane = new Plane();
				_plane->SetPosition(posX, posY);
				_plane->SetPostionEndPoint(posX2, posY2);
				_plane->SetVelocityDefault((float)velo);

				this->AddObject(_plane);

				break;
			}
		}
	} else {
		printf(">>>> load file failed!! \n");
	}
}

void SceneManager::AddObject(Object* object)
{
	this->m_ObjectList.push_back(object);
}

void SceneManager::Update(float frameTime)
{
	list<Object*>::iterator iter_obj = this->m_ObjectList.begin();
	for (; iter_obj != m_ObjectList.end(); iter_obj++)
	{
		(*iter_obj)->Update(frameTime);
	}
	m_collidMgr->DetectCollision(m_ObjectList);
}

void SceneManager::Render()
{
	list<Object*>::iterator iter_obj = this->m_ObjectList.begin();
	for (; iter_obj != m_ObjectList.end(); iter_obj++)
	{
		(*iter_obj)->Render();
	}
}

void SceneManager::TouchActionDown(ESContext *esContext,int x, int y)
{
	//printf("SceneManager touch DOWN %d, %d \n", x, y);
	m_touch->touchState = StateDown;
	SetTouchPosition(x, y);

	list<Object*>::iterator iter_obj = this->m_ObjectList.begin();
	for (; iter_obj != m_ObjectList.end(); iter_obj++)
	{
		if ((*iter_obj)->IsInRect(x, y))
		{
			this->m_selectedObject = *iter_obj;
			this->m_selectedObject->SetSelect(true);
			this->m_selectedObject->SetAcceleration(0, 0);
			this->m_selectedObject->SetVelocity(0, 0);
			break;
		}
	}
}

void SceneManager::TouchActionUp(ESContext *esContext,int x, int y)
{
	//printf("SceneManager touch UP %d, %d \n", x, y);
	m_touch->touchState = StateUp;
	SetTouchPosition(x, y);

	if (this->m_selectedObject)
	{	
		this->m_selectedObject->SetSelect(false);
		this->m_selectedObject->SetDestPos(-1, -1);
		
		this->m_selectedObject->AddForce(0, m_selectedObject->GetMass() * Object::k_Gravity);
		this->m_selectedObject = NULL;
	}
}

void SceneManager::TouchActionMove(ESContext *esContext,int x, int y)
{
	//printf("SceneManager touch MOVE %d, %d \n", x, y);
	m_touch->touchState = StateMove;
	SetTouchPosition(x, y);

	if (this->m_selectedObject)
	{
		this->m_selectedObject->HandleTouchAction(this->m_touch);

		float deltaX = x - m_selectedObject->GetCenterPosX();
		float deltaY = y - m_selectedObject->GetCenterPosY();

		float distance = sqrt(deltaX * deltaX + deltaY * deltaY);
		if (distance != 0)
		{
			deltaX = deltaX / distance;
			deltaY = deltaY / distance;
		}
		this->m_selectedObject->SetVelocity(
			deltaX * m_selectedObject->GetVelocityDefault(),
			deltaY * m_selectedObject->GetVelocityDefault()
			);

		this->m_selectedObject->AddForce(deltaX, deltaY); //TODO : seem wrong??
		
		this->m_selectedObject->SetDestPos(x, y);

	}
}

void SceneManager::SetTouchPosition(int x, int y)
{
	m_touch->prevPosX = m_touch->currPosX;
	m_touch->prevPosY = m_touch->currPosY;
	m_touch->currPosX = x;
	m_touch->currPosY = y;
}